package disruptor;

import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.Disruptor;

import java.util.concurrent.Executors;

/**
 * @author: 李德才
 * @description:
 * @create: 2020-12-20 19:51
 **/
public class DisruptorTest02 {


    public static void main(String[] args) {

        /**
         *  Disruptor 构建了一个环形数组
         *  这个数组首位相连，
         *  在初始化的时候，通过 event 工厂，按照数组长度创建全部  event 对象，
         *  当数组中的对象需要变化时， 直接改变对象中的值（覆盖），不需要重新创建
         *  简单用房详见 DisruptorTest03
         */

        // The factory for the event 创建event 的工厂
        DisruptorEventFactory disruptorEventFactory = new DisruptorEventFactory();
        // Specify the size of the ring buffer, must be power of 2.
        // 数组长度，一定是2的幂次方
        int bufferSize = 1024;
        // Construct the Disruptor 创建
        Disruptor<DisruptorEvent> disruptor = new Disruptor<>(disruptorEventFactory, bufferSize, Executors.defaultThreadFactory());
        // Connect the handler 指定处理程序
        disruptor.handleEventsWith(new DisruptorEventHandler(1));
        // Start the Disruptor, starts all threads running
        // 启动程序，起开所有线程
        disruptor.start();
        // Get the ring buffer from the Disruptor to be used for publishing.
        RingBuffer<DisruptorEvent> ringBuffer = disruptor.getRingBuffer();
        EventTranslator<DisruptorEvent> eventEventTranslator = new EventTranslator<DisruptorEvent>() {
            @Override
            public void translateTo(DisruptorEvent disruptorEvent, long l) {
                disruptorEvent.set(8000L);
            }
        };
        ringBuffer.publishEvent(eventEventTranslator);

        /**
         * 允许设置指定值
         */
//      EventTranslatorTwoArg
//      EventTranslatorThreeArg
        EventTranslatorOneArg<DisruptorEvent, Long> eventTranslatorOneArg = new EventTranslatorOneArg<DisruptorEvent, Long>() {
            @Override
            public void translateTo(DisruptorEvent disruptorEvent, long l, Long longNumber) {
                disruptorEvent.set(longNumber);
            }
        };
        ringBuffer.publishEvent(eventTranslatorOneArg, 3L);

        EventTranslatorVararg<DisruptorEvent> eventTranslatorVararg = new EventTranslatorVararg<DisruptorEvent>() {
            @Override
            public void translateTo(DisruptorEvent disruptorEvent, long l, Object... objects) {
                long result = 0;
                for (Object o : objects) {
                    long i = (Long) o;
                    result += l;
                }
                disruptorEvent.set(result);
            }
        };
        ringBuffer.publishEvent(eventTranslatorVararg, 1L, 2L, 3L, 5L, 6L, 4L, 8L, 456L, 4654L, 56L, 4L);
        disruptor.shutdown();

    }
}
